﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Firecracker.Bootstrapper.Interception;
using Mono.Cecil;
using Mono.Cecil.Pdb;

namespace Firecracker.Bootstrapper
{
  public class Program
  {

    public static void Main(String[] args)
    {
      try
      {
        foreach (var s in args)
        {
          if (!new FileInfo(s).Exists)
          {
            Console.WriteLine("The argument: " + s + " does not exist!");
            return;
          }
        }

        Console.WriteLine(args);
        Console.WriteLine(Path.GetFullPath("."));
        string instrumentingAssemblyPath = args[0];
        string instrumentAssembly = Path.GetFileNameWithoutExtension(instrumentingAssemblyPath);

        var pdbName = Path.ChangeExtension(instrumentingAssemblyPath, "pdb");
        var readerParameters = new ReaderParameters { AssemblyResolver = GlobalAssemblyResolver.Instance };
        var writerParameters = new WriterParameters();
        Console.WriteLine("Checking for pdb: " + pdbName);
        if (File.Exists(pdbName))
        {
          Console.WriteLine("Fixing pdb...");
          var symbolReaderProvider = new PdbReaderProvider();
          readerParameters.SymbolReaderProvider = symbolReaderProvider;
          readerParameters.ReadSymbols = true;
          writerParameters.WriteSymbols = true;
        }

        var instrument = GlobalAssemblyResolver.Instance.Resolve(instrumentAssembly, readerParameters);
        var testassembly = GlobalAssemblyResolver.Instance.Resolve(Path.GetFileNameWithoutExtension(args[1]));


        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var container = new CompositionContainer(catalog);


        var processor = container.GetExportedValue<AssemblyProcessor>();
        processor.Process(instrument, testassembly);

        instrument.Write(args[0], writerParameters);
      }
      catch (Exception e)
      {
        Console.WriteLine(e.Message);
        Console.WriteLine(e.StackTrace);
      }
    }
  }
}
